﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using centraldba_library.Admin;
using centraldba.msx_config_addin.Events;
using Microsoft.SqlServer.Dac;

namespace centraldba.msx_config_addin.Forms
{
    /// <summary>
    /// Interaction logic for connect_database.xaml
    /// </summary>
    public partial class connect_database : Window
    {
        private string _connStr;
        private msx_server ms;

        #region " Constructor "

        public connect_database(string connectionStringTemplate)
        {
            InitializeComponent();

            ms = null;
            _connStr = connectionStringTemplate;

            cmdOK.IsEnabled = false;
        }

        #endregion
        
        #region " Events "

        public event EventHandler<SelectedServerEventArgs<msx_server>> MSXServerSelected;

        #endregion

        #region " Method "

        private void EnableForm(bool is_enabled)
        {
            txtServerName.IsEnabled = is_enabled;
            txtDatabaseName.IsEnabled = is_enabled;
            cmdCancel.IsEnabled = is_enabled;

            if (!txtServerName.Text.Trim().Length.Equals(0) && !txtDatabaseName.Text.Trim().Length.Equals(0))
                cmdOK.IsEnabled = is_enabled;
        }

        private void cmdCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void cmdOK_Click(object sender, RoutedEventArgs e)
        {
            EnableForm(false);

            // ms is Still NULL; missing data
            if (ms == null)
            {
                MessageBox.Show("Error connecting to database " + txtDatabaseName.Text.Trim() + " on server " + txtServerName.Text.Trim());
            }
            else
            {
                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerSupportsCancellation = false;
                bw.WorkerReportsProgress = false;

                bw.DoWork += delegate(object s, DoWorkEventArgs args)
                {
                    string[] s_args = args.Argument.ToString().Split('|');
                    string database_name = s_args[0].ToString().Trim();
                    string AdminEmailAccount = s_args[1].ToString().Trim();
                    string AdminEmailDomainName = s_args[2].ToString().Trim();
                    string AdminSmtpServer = s_args[3].ToString().Trim();
                    string SqlServiceAccountDomainGroup = s_args[4].ToString().Trim();

                    // Load the Package and connect to the server
                    DacPackage pkg = DacPackage.Load(".\\Resources\\centraldba_msx_db.dacpac");
                    DacServices ds = new DacServices(ms.connection_string);
                    ds.Message += new EventHandler<DacMessageEventArgs>(ds_Message);

                    // Setup the Deployment Options
                    DacDeployOptions ddo = new DacDeployOptions
                    {
                        IncludeCompositeObjects = true,
                        ScriptDatabaseOptions = true,
                        BlockOnPossibleDataLoss = true,
                        VerifyDeployment = false
                    };
                    ddo.SqlCommandVariableValues.Add("AdminEmailAccount", AdminEmailAccount);
                    ddo.SqlCommandVariableValues.Add("AdminEmailDomainName", AdminEmailDomainName);
                    ddo.SqlCommandVariableValues.Add("AdminSmtpServer", AdminSmtpServer);
                    ddo.SqlCommandVariableValues.Add("SqlServiceAccountDomainGroup", SqlServiceAccountDomainGroup);

                    // Deploy the package to the server
                    try
                    {
                        ds.Deploy(pkg, database_name, true, ddo);
                    }
                    catch (Exception ex) 
                    {
                        SetStatus("\r\r\rERROR:\r------------------------------------------------\r" + ex.Message);
                    }

                    // Cleanup Memory References
                    ddo = null;
                    if (pkg != null)
                        pkg.Dispose();
                    pkg = null;
                    ds = null;
                };

                bw.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
                {
                    bw.Dispose();
                    bw = null;

                    MessageBox.Show("Complete");
                };

                bw.RunWorkerAsync(txtDatabaseName.Text.Trim() + "|" + txtAdminEmailAccount.Text.Trim() + "|" + txtAdminEmailDomainName.Text.Trim() + "|" + txtAdminSmtpServer.Text.Trim() + "|" + txtSqlServiceAccountDomainGroup.Text.Trim());

                // Update the UI
                //MSXServerSelected(this, new SelectedServerEventArgs<msx_server>(ms));
                //this.Close();
            }

            EnableForm(true);
        }

        void ds_Message(object sender, DacMessageEventArgs e)
        {
            SetStatus(e.Message.ToString());
        }

        void SetStatus(string message)
        {
            Dispatcher.BeginInvoke((Action)delegate
            {
                if (!txtStatus.Text.Trim().Length.Equals(0))
                    txtStatus.Text += "\r";

                txtStatus.Text += message;
                txtStatus.ScrollToEnd();
            });
        }

        private void txtStatus_GotFocus(object sender, RoutedEventArgs e)
        {
            txtStatus.SelectAll();
            txtStatus.Copy();
        }

        private void Server_LostFocus(object sender, RoutedEventArgs e)
        {
            // Disable the form to keep user from messing things up
            EnableForm(false);

            // Grab and pre-process form values
            string server_name, database_name;
            server_name = txtServerName.Text.Trim();
            database_name = txtDatabaseName.Text.Trim();

            // Server and Database must both be entered
            if (server_name.Equals(string.Empty) || database_name.Equals(string.Empty))
            {
                ms = null;
            }
            else
            {
                // A database server connection has already been made
                if (ms != null)
                {
                    // Server and Database are not the same as the current msx server item; get rid of the current one
                    if (!ms.server_name.Equals(server_name) && !ms.database_name.Equals(database_name))
                        ms = null;
                }

                // Connect to the database server if the connection doesn't already exist
                if (ms == null)
                    ms = new msx_server(_connStr, server_name, database_name);

                // Blank out config settings (defaults)
                txtAdminEmailAccount.Text = "";
                txtAdminEmailDomainName.Text = "";
                txtAdminSmtpServer.Text = "";
                txtSqlServiceAccountDomainGroup.Text = "";

                // Set values based on config settings
                if (ms.config_settings != null)
                {
                    if (ms.config_settings.ContainsKey("AdminEmailAccount"))
                        txtAdminEmailAccount.Text = ms.config_settings["AdminEmailAccount"].ToString();

                    if (ms.config_settings.ContainsKey("AdminEmailDomainName"))
                        txtAdminEmailDomainName.Text = ms.config_settings["AdminEmailDomainName"].ToString();

                    if (ms.config_settings.ContainsKey("AdminSmtpServer"))
                        txtAdminSmtpServer.Text = ms.config_settings["AdminSmtpServer"].ToString();

                    if (ms.config_settings.ContainsKey("SqlServiceAccountDomainGroup"))
                        txtSqlServiceAccountDomainGroup.Text = ms.config_settings["SqlServiceAccountDomainGroup"].ToString();
                }
            }

            // Re-enable the form
            EnableForm(true);
        }

        #endregion

        private void Text_GotFocus(object sender, RoutedEventArgs e)
        {
            ((TextBox)sender).SelectAll();
        }

    }
}
